﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
using System.Windows;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;

namespace Istacee.Personal.Desktop.TimeWatcher
{
    public class TrackedTask : ViewModelBase
    {
        public DateTime lastStartup;
        private string _name;
        private bool _status;
        private string _elapsedTime;
        private Timer refreshTimer;
        private bool _periodBasis;
        private bool _ponctualBasis;
        private DateTime _alarmTime;
        private Visibility _detailVisiblity;

        public Visibility DetailVisiblity
        {
            get { return _detailVisiblity; }
            set
            {
                _detailVisiblity = value;
                RaisePropertyChanged("DetailVisiblity");
            }
        }

        public DateTime AlarmTime
        {
            get { return _alarmTime; }
            set { _alarmTime = value; }
        }

        public bool PonctualBasis
        {
            get { return _ponctualBasis; }
            set { _ponctualBasis = value; }
        }

        public string Name
        {
            get { return _name; }
            set
            {
                if (value != this._name)
                {
                    _name = value;
                    RaisePropertyChanged("Name");
                }
            }
        }
        public bool Status
        {
            get { return _status; }
            set
            {
                if (value != this._status)
                {
                    _status = value;
                    RaisePropertyChanged("Status");
                }
            }
        }
        public string ElapsedTime
        {
            get { return _elapsedTime; }
            set
            {
                if (value != this._elapsedTime)
                {
                    _elapsedTime = value;
                    RaisePropertyChanged("ElapsedTime");
                }
            }
        }

        public List<Tuple<DateTime, DateTime>> Periods { get; set; }
        public ICommand TaskActionCommand { get; set; }
        public ICommand DetailVisibilityCommand { get; set; }

        public TrackedTask()
        {
            Name = "<Enter your task name>";
            Periods = new List<Tuple<DateTime, DateTime>>();
            TaskActionCommand = new RelayCommand(TaskAction);
            DetailVisibilityCommand = new RelayCommand(SetVisiblity);
            refreshTimer = new Timer();
            refreshTimer.AutoReset = true;
            refreshTimer.Elapsed += RefreshTimerOnElapsed;
            refreshTimer.Start();
            this.Status = false;
            this.PonctualBasis = true;
            this.DetailVisiblity = Visibility.Collapsed;
        }

        private void RefreshTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            this.ElapsedTime = this.GetEllapsedTime().ToString("c");
        }

        private void SetVisiblity()
        {
            this.DetailVisiblity = this.DetailVisiblity == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
        }

        private void TaskAction()
        {
            if(!Status)
                Start();
            else
                Stop();
        }

        public void Start()
        {
            if (!Status)
            {
                lastStartup = DateTime.Now;
                Status = true;
            }
        }

        public void Stop()
        {
            if (Status)
            {
                Periods.Add(new Tuple<DateTime, DateTime>(lastStartup, DateTime.Now));
                Status = false;
            }
        }

        public TimeSpan GetEllapsedTime()
        {
            var result = from period in this.Periods
                         select period.Item1.Subtract(period.Item2);

            TimeSpan current = Status ? DateTime.Now.Subtract(lastStartup) : new TimeSpan(0);

            return result.ToList().Sum(t => t.Duration()).Add(current);
        }
    }

    public static class StatisticExtensions
    {
        public static TimeSpan Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, TimeSpan> selector)
        {
            return source.Select(selector).Aggregate(TimeSpan.Zero, (t1, t2) => t1 + t2);
        }
    }
}
